package com.litbw.gui;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;

import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import com.litbw.dbbackend.DBContestAdapter;
import com.litbw.event.Contest;
import com.litbw.event.Event;
import com.litbw.publicobservable.BasicUIMessage;
import com.litbw.publicobservable.EventDetailMessage;
import com.litbw.publicobservable.LoginMessage;
import com.litbw.publicobservable.LogoutMessage;
import com.litbw.publicobservable.RegisterMessage;
import com.litbw.user.User;
import com.litbw.user.UserRole;

/**
 * The EventDetailPanel displays data regarding the selected event (from 
 * Event panel). It also provides a button which allows users to Register for
 * and Event. Using LoginMessage and LogoutMessage signals the register button
 * is enabled and disabled respectively. Also, when the user is NOT logged in
 * a simple message directs them to the top to login before the button will
 * be enabled.
 * @author Michael Morris
 * @edited Silvia Chita
 */
public class EventDetailPanel extends AbstractObservablePanel {

	/**
	 * The name of this panel.
	 */
	private static final String DEF_NAME = "Event Details";
	
	/**
	 * The Login message near bottom of panel.
	 */
	private static final String LOGIN_MSG = "Login to continue with Event Registration!  ";
	
	/**
	 * Generated serial version UID.
	 */
	private static final long serialVersionUID = 3833921099764289502L;

	/**
	 * The pane which displays the event details through HTML.
	 */
	private JEditorPane detail_wnd;
	
	/**
	 * The Register button.
	 */
	private JButton register_btn;
	
	/**
	 * The login label.
	 */
	private JLabel login_lbl;
	
	/**
	 * True if an organizer is logged in. False by default.
	 */
	private boolean loggedInOrganizer;
	/**
	 * True is judge is logged in. False otherwise.
	 */
	private boolean loggedInJudge;

	/**
	 * Create a new EventDetailPanel.
	 */
	public EventDetailPanel() {
		super();
		setLayout(new BorderLayout());
		setName(DEF_NAME);
		addComponents();
		updateLoggedInState(false);
		
	}
	
	/**
	 * Add and setup the sub components necessary for this panel.
	 */
	private void addComponents() {
		
		// Setup editor pane and scroller, then add to panel.
		detail_wnd = new JEditorPane();
		detail_wnd.setContentType("text/html");
		detail_wnd.setEditable(false);
		
		final JScrollPane scroll = new JScrollPane(detail_wnd);
		scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		add(scroll, BorderLayout.CENTER);
		
		// Setup the small Register button panel
		final JPanel event_register_panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		register_btn = new JButton("Register For Event");
		register_btn.addActionListener(new ActionListener() {
			@Override
			/**
			 * @author Trygve Stageberg
			 */
			public void actionPerformed(ActionEvent arg0) {
				setChanged();
				notifyObservers(new RegisterMessage(RegisterMessage.RegisterSignal.UPDATE));
				setChanged();
				notifyObservers(new BasicUIMessage(BasicUIMessage.UISignal.SHOW_REGISTER_EVENT));
			}
		});
		register_btn.setEnabled(false);
		login_lbl = new JLabel(LOGIN_MSG); 
		
		event_register_panel.add(login_lbl);
		event_register_panel.add(register_btn);
		
		add(event_register_panel, BorderLayout.SOUTH);
		
		

		//need to update logged in state if user is logged in.
		
	}
	
	/**
	 * Builds the HTML which is displayed in the editor.
	 * @param e The Event to gather data from.
	 * @return A String containing the details of the even or the literal
	 * "Error: No data to display!" if the Event was null.
	 * @edited Silvia Chita
	 */
	private String buildBasicDetailHTML(final Event e) {
		
		String rtn = "Error: No data to display!";
		
		if (e != null) {
		
			final Contest[] contests = DBContestAdapter.getContestsForEvent(Integer.valueOf(e.getId()));
			int numCategories = 0;
			if (contests != null)
				numCategories = contests.length;
			
			final StringBuilder sb = new StringBuilder();
			
			sb.append("<HTML><BODY><center><h1>Event ID ");
			sb.append(e.getId());
			sb.append("</h1><HR><h3>When: ");
			sb.append(e.getDate());
			sb.append("<BR>Where: <u>");
			sb.append(e.getLocation());
			sb.append("</u></h3></center>");
			sb.append("<h2><u>Details</u></h2>");
			sb.append("<ul><li>");
			sb.append(numCategories);
			sb.append(" Weaving Competition Categories</li>");
			sb.append("<li>Hundreds of Awesome Prizes</li>");
			sb.append("<li>Great Food</li>");
			sb.append("<li>Free Parking</li></ul>");
			sb.append("<h2><u>Hours</u></h2>");
			sb.append("<ul><li>");
			sb.append(e.getDate());
			sb.append(": ");
			sb.append(e.getTime());
			sb.append("</li></ul>");
			sb.append("<h2><u>Price</u></h2><ul><li>$5 to attend</li>");
			sb.append("<li>$10 to enter a contest</li><li>$10 application fee for judges</li>");
			
			sb.append("<h2><u>Contest Categories</u></h2>");
			
			for (Contest c : e.getCategories()) {
				sb.append("<ul><li>");
				sb.append(c.getDescription());
				sb.append("</li></ul>");
				if (loggedInJudge) {
					
				}
				
			}
			
			if (loggedInOrganizer) {
				sb.append("<h2><u>Registered Users</u></h2>");
				for (User u : e.getRegistrants()) {
					sb.append("<ul><li>");
					sb.append(u.getName());
					sb.append("</li></ul>");
				}
			}
			
			sb.append("</ul><h2><u>Registration Information</u></h2><ul>");
			sb.append("<li>Must be 18 to register as contestant/judge</li>");
			sb.append("<li>Click below to Register</li></ul>");
			sb.append("</BODY></HTML>");
			
			rtn = sb.toString();
		
		}
		
		return rtn;
		
	}
	
	/**
	 * Update the panels UI based on the current users login state.
	 * @param logged_in True if logged in.
	 */
	private void updateLoggedInState(final boolean logged_in) {
		
		// Show/Hide and Enable/Disale the register button and login label.
		if (logged_in) {
			login_lbl.setVisible(false);
			register_btn.setEnabled(true);
		} else {
			login_lbl.setVisible(true);
			register_btn.setEnabled(false);
		}
		
	}
	
	@Override
	public void update(final Observable obs, final Object arg) {
		
		// Check for EventDetailMessages
		if (arg instanceof EventDetailMessage) {
			
			final EventDetailMessage msg = (EventDetailMessage)arg;
			final Event data = msg.getEvent();
			
			// TODO: remove after debug.
			System.out.println("EventDetailPanel recieved signal: " + msg.getSignal());
			System.out.println("      EventData: " + data);
			
			// Discipher signal
			switch (msg.getSignal()) {
				case UPDATE:
					
					// Update with the supplied data, if we can, and scroll to top.
					if (data != null) {
						detail_wnd.setText(buildBasicDetailHTML(data));
						detail_wnd.setCaretPosition(0);
					}
					
					break;
				case CLEAR:
					
					break;
			}
			
		// Check for login/logout and update UI accordingly.
		} else if (arg instanceof LoginMessage) {
			updateLoggedInState(true);
			if (((LoginMessage) arg).getUser().getRole() == UserRole.JUDGE) {
				loggedInJudge = true;
			}
			if (((LoginMessage) arg).getUser().getRole() == UserRole.ORGANIZER) {
				loggedInOrganizer = true;
			}
		} else if (arg instanceof LogoutMessage) {
			updateLoggedInState(false);
		}
		
	}
	
}
